package cn.com.duiba.millionaire.center.biz.service.impl;

import cn.com.duiba.millionaire.center.api.dto.MillionaireActivityDto;
import cn.com.duiba.millionaire.center.biz.bo.ConsumeAccountParam;
import cn.com.duiba.millionaire.center.biz.service.MillionaireActivityService;
import cn.com.duiba.millionaire.center.biz.service.OpenPrizeService;
import cn.com.duiba.millionaire.center.biz.service.UserAccountService;
import cn.com.duiba.millionaire.center.biz.service.WinnerListService;
import org.apache.commons.collections.CollectionUtils;
import org.javatuples.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by zzy on 2018/1/20.
 */
@Service
public class OpenPrizeServiceImpl implements OpenPrizeService {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAnswerHanderService.class);
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private WinnerListService winnerListService;
    @Autowired
    private MillionaireActivityService millionaireActivityService;
    @Autowired
    private UserAccountService userAccountService;

    /**
     * @param activityId
     */
    @Override
    public void openPrize(Long activityId) {
        if (!uniqueCheck(String.valueOf(activityId))) {
            return;
        }
        //设置活动已使用过
        millionaireActivityService.changeAlreadyUsed(activityId);
        Long totalMoney = findActivityTotalMoney(activityId);
        if (totalMoney == null || totalMoney < 100) {
            LOGGER.warn("奖金小于1元，不发奖");
            return;
        }
        Long winnerNum = findWinnerNum(activityId);
        if (winnerNum == null || winnerNum <= 0) {
            LOGGER.warn("中奖人数小于1，不发奖");
            return;
        }
        Long winMoney = totalMoney / winnerNum;
        if (winMoney <= 10) {
            LOGGER.warn("分得奖金小于0.1元");
        }
        Set<Pair<Long, Long>> winners = findAllWinners(activityId);
        if (CollectionUtils.isEmpty(winners)) {
            LOGGER.warn("中奖列表为空");
            return;
        }
        int len = winners.size();
        if(len<=1000){
            userAccountHandle(activityId,winMoney,winners);
            return;
        }

        Set<Pair<Long, Long>> tempWinners = new HashSet<>();
        for(Pair<Long, Long> cidAndAppId : winners){
            tempWinners.add(cidAndAppId);
            if(tempWinners.size() ==1000){
                userAccountHandle(activityId,winMoney,tempWinners);
                tempWinners.clear();
            }
        }

        if(!tempWinners.isEmpty()){
            userAccountHandle(activityId,winMoney,tempWinners);
        }

    }

    private void userAccountHandle(Long activityId,Long winMoney,Set<Pair<Long, Long>> winners){
        ConsumeAccountParam consumeAccountParam = new ConsumeAccountParam();
        consumeAccountParam.setActivityId(activityId);
        consumeAccountParam.setAmount(winMoney.intValue());
        consumeAccountParam.setCidAppIdSet(winners);
        userAccountService.addConsumerAccount(consumeAccountParam);
    }

    /**
     * 查询分会场活动奖金金额
     *
     * @param activityId
     * @return
     */
    private Long findActivityTotalMoney(Long activityId) {
        MillionaireActivityDto millionaireActivityDto = millionaireActivityService.findMillionaireActivityById(activityId);
        if (millionaireActivityDto != null) {
            return millionaireActivityDto.getTotalMoney();
        }
        return null;
    }

    /**
     * 查询中奖人数
     *
     * @param activityId
     * @return
     */
    private Long findWinnerNum(Long activityId) {
        return winnerListService.countWinners(activityId);
    }

    private Set<Pair<Long, Long>> findAllWinners(Long activityId) {
        return winnerListService.findAllWinners(activityId);
    }

    private boolean uniqueCheck(String key) {
        Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, "0");
        if (!ret) {
            return false;
        }
        redisTemplate.expire(key, 2, TimeUnit.HOURS);
        return true;
    }
}
